 /* 
  * Copyright (C) 2012 maxim 
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  */

#include "user_threads.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include "tests.h"

/* Basic thread test*/

static int thread1(void* arg) {

	msg_with_expected_order(2, "we enter thread %d", uthread_self());
	fflush(stdout);
	delay(300000000, '1');

	msg_with_expected_order(6, "we exit thread %d", uthread_self());
	fflush(stdout);
	return 0;
}

static int thread2(void* arg) {

	msg_with_expected_order(3, "we enter thread %d", uthread_self());
	fflush(stdout);
	delay(300000000, '2');
	msg_with_expected_order(5, "we exit thread %d", uthread_self());
	fflush(stdout);
	return 0;
}

static int thread3(void* arg) {

	msg_with_expected_order(4, "we enter thread %d", uthread_self());
	fflush(stdout);
	delay(300000000, '3');
	msg_with_expected_order(7, "we exit thread %d", uthread_self());
	fflush(stdout);
	return 0;
}

void test1()
{
	msg("\nRunning test #1...");
	reset_counter();
	assert(uthread_create(thread1, NULL, UTHREAD_MIN_PRIO) == 1); // this one had the higher priority 
	assert(uthread_create(thread2, NULL, UTHREAD_MAX_PRIO) == 2);
	assert(uthread_create(thread3, NULL, UTHREAD_MIN_PRIO) == 3);

	assert(uthread_self() == 0);
	msg_with_expected_order(1, "we enter thread %d", uthread_self());

	assert (uthread_join(3, NULL) == UTHREAD_SUCCESS);

	// since we join on thread 3 which has lowest priority, the thread 2 ought to end by now */

	assert (uthread_cancel(2) == UTHREAD_FAIL);

	assert (uthread_join(1, NULL) == UTHREAD_SUCCESS);
	assert (uthread_join(1, NULL) == UTHREAD_INVALID);
	assert (uthread_join(2, NULL) == UTHREAD_SUCCESS);
	assert (uthread_join(3, NULL) == UTHREAD_INVALID); 

	assert (uthread_join(2, NULL) == UTHREAD_INVALID);
	msg("8. we exit thread %d", uthread_self());
}
